<script setup lang="ts">
import { ref, nextTick, onMounted, onUnmounted, watch } from 'vue';
import OpenAI from 'openai';
import { Marked } from 'marked';
import { markedHighlight } from 'marked-highlight';
import hljs from 'highlight.js';

const marked = new Marked(
  markedHighlight({
    emptyLangClass: 'hljs',
    langPrefix: 'hljs language-',
    highlight(code, lang) {
      const language = hljs.getLanguage(lang) ? lang : 'plaintext';
      return hljs.highlight(code, { language }).value;
    },
  })
);

type ChatMessage = {
  role: 'system' | 'user' | 'assistant';
  content: string;
};

const openai = new OpenAI({
  baseURL: 'https://api.deepseek.com',
  apiKey: import.meta.env.VITE_DEEPSEEK_API_KEY,
  dangerouslyAllowBrowser: true,
});

const userInput = ref('');
const conversation = ref<ChatMessage[]>([]);
const isLoading = ref(false);
const conversationContainer = ref<HTMLElement | null>(null);

const textareaHeight = ref('auto');
const hiddenDiv = ref<HTMLElement | null>(null);
const textareaRef = ref<HTMLTextAreaElement | null>(null);

const adjustTextareaHeight = () => {
  if (hiddenDiv.value && textareaRef.value) {
    // 将 textarea 的内容复制到隐藏的 div 中
    hiddenDiv.value.innerText = userInput.value;
    // 获取隐藏 div 的高度并应用到 textarea
    textareaHeight.value = `${hiddenDiv.value.offsetHeight - 10}px`;
  }
};

// 动态加载 CSS 文件
const loadHighlightTheme = (isDarkMode: boolean) => {
  const linkElement = document.getElementById('highlight-theme') as HTMLLinkElement | null;
  const theme = isDarkMode ? 'github-dark' : 'github';

  if (linkElement) {
    linkElement.href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/${theme}.min.css`;
  } else {
    const link = document.createElement('link');
    link.id = 'highlight-theme';
    link.rel = 'stylesheet';
    link.href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/${theme}.min.css`;
    document.head.appendChild(link);
  }
};

// 检测系统主题
const detectSystemTheme = () => {
  const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
  loadHighlightTheme(isDarkMode);
};

// 监听系统主题变化
const themeChangeListener = (event: MediaQueryListEvent) => {
  loadHighlightTheme(event.matches);
};

onMounted(() => {
  detectSystemTheme();
  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', themeChangeListener);
  // 初始化时调整高度
  adjustTextareaHeight();
});

onUnmounted(() => {
  window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', themeChangeListener);
});

// 监听 userInput 的变化，动态调整 textarea 的高度
watch(userInput, () => {
  adjustTextareaHeight();
});

const sendMessage = async () => {
  if (!userInput.value.trim()) return;
  isLoading.value = true;
  conversation.value.push({ role: 'user', content: userInput.value });

  try {
    const response = await openai.chat.completions.create({
      model: 'deepseek-reasoner',
      messages: conversation.value,
    });

    const aiResponse = response.choices[0].message.content;
    if (aiResponse !== null) {
      conversation.value.push({ role: 'assistant', content: aiResponse });
    }
  } catch (error) {
    console.error('Error:', error);
    conversation.value.push({ role: 'assistant', content: 'Sorry, something went wrong.' });
  } finally {
    isLoading.value = false;
    userInput.value = '';

    await nextTick();
    document.querySelector('textarea')?.focus(); // Auto-Focus Textarea
  }
};

const escapeHtml = (str: string): string => {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
};

// 渲染内容
const renderContent = (message: ChatMessage) => {
  if (message.role === 'assistant') {
    return marked.parse(message.content);
  } else {
    return escapeHtml(message.content);
  }
};

const scrollToMessage = (index: number) => {
  const messageElements = document.querySelectorAll('.message');
  if (messageElements[index]) {
    messageElements[index].scrollIntoView({
      behavior: 'smooth',
      block: 'start',
    });

    messageElements.forEach((el) => el.classList.remove('active'));
    messageElements[index].classList.add('active');
  }
};
</script>

<template>
  <div class="layout">
    <div class="sidebar">
      <div class="sidebar-header">
        <h1>DeepSeek</h1>
      </div>
      <div class="sidebar-content">
        <p>Conversation History</p>
        <ul>
          <template v-for="(item, index) in conversation" :key="index">
            <li v-if="item.role === 'user'" @click="scrollToMessage(index)">
              {{ index / 2 + 1 }}: {{ item.content.slice(0, 50) }}
            </li>
          </template>
        </ul>
      </div>
    </div>
    <div class="main-content">
      <div class="conversation" ref="conversationContainer">
        <div v-for="(message, index) in conversation" :key="index" :class="['message', message.role]">
          <div class="role">{{ message.role === 'user' ? 'You' : 'AI' }}</div>
          <div class="content" v-html="renderContent(message)"></div>
        </div>
        <div v-if="isLoading" class="message assistant">
          <div class="role">AI</div>
          <div class="content">
            <span class="loading">Thinking...</span>
          </div>
        </div>
      </div>
      <div class="input-area">
        <!-- 隐藏的 div 用于计算高度 -->
        <div ref="hiddenDiv" class="hidden-div"></div>
        <textarea ref="textareaRef" v-model="userInput" @keyup.enter="sendMessage"
          placeholder="Type your message here..." :style="{ height: textareaHeight }" :disabled="isLoading"></textarea>
        <button @click="sendMessage" :disabled="isLoading">
          {{ isLoading ? 'Sending...' : 'Send' }}
        </button>
      </div>
    </div>
  </div>
</template>